Skip to content

Implement identity-aware routing RFC with route policies terminology#3758

Draft
rkoster wants to merge 4 commits intomainfrom
enhance-add-access-rule-ux
Draft

Implement identity-aware routing RFC with route policies terminology#3758
rkoster wants to merge 4 commits intomainfrom
enhance-add-access-rule-ux

Conversation

@rkoster
Copy link
Copy Markdown

@rkoster rkoster commented Apr 10, 2026

Summary

This PR implements the identity-aware routing RFC (cloudfoundry/community#1438) in the CF CLI, including the complete terminology rebrand from "access rules" to "route policies" and "selector" to "source".

Terminology Update (Breaking Change):

  • Commands: access-rulesroute-policies, add-access-ruleadd-route-policy, remove-access-ruleremove-route-policy
  • Flags: --enforce-access-rules--enforce-route-policies, --selector--source
  • API paths: /v3/access_rules/v3/route_policies
  • Resource types: AccessRuleRoutePolicy

This is an acceptable breaking change since the feature has not been GA-released.

Motivation

The original POC implementation used "access rules" terminology, but the RFC was updated to use "route policies" for better alignment with existing CF concepts. Additionally, the commands required users to manually construct GUID-based selectors (e.g., cf:app:d76446a1-f429-4444-8797-be2f78b75b08), which was cumbersome and error-prone.

This PR follows CF CLI conventions from commands like add-network-policy to provide a user-friendly interface with name-based flags.

Changes

1. Terminology Rebrand (Commit: a0ffff8)

Complete rebrand across 95 files:

  • Commands: route-policies, add-route-policy, remove-route-policy
  • Flags: --enforce-route-policies, --source, --source-app, --source-space, --source-org, --source-any
  • API endpoints: /v3/route_policies
  • Query parameters: sources, source_guids
  • Resource fields: RoutePolicy.Source, Domain.EnforceRoutePolicies, Domain.RoutePoliciesScope
  • Table columns: Updated to show "source" terminology

Rationale (per RFC commit be8d74c):

The term "route policy" is more idiomatic within Cloud Foundry, which already uses "network policies" for app-to-app network access. This naming convention better communicates that these are routing-layer policies that control which sources can access specific routes.

2. Command Interface Improvements

Before:

cf add-access-rule RULE_NAME DOMAIN SELECTOR --hostname HOST
cf remove-access-rule RULE_NAME DOMAIN --hostname HOST

After:

# add-route-policy examples
cf add-route-policy apps.identity --source-app frontend-app --hostname backend
cf add-route-policy apps.identity --source-space monitoring --hostname api
cf add-route-policy apps.identity --source-org platform --hostname shared-api
cf add-route-policy apps.identity --source-any --hostname public-api

# Cross-space/org access
cf add-route-policy apps.identity --source-app client --source-space prod-space --source-org prod-org --hostname api

# Advanced: raw source still supported
cf add-route-policy apps.identity --source cf:app:GUID --hostname backend

# remove-route-policy
cf remove-route-policy apps.identity --source cf:app:GUID --hostname backend

3. New Flags

add-route-policy:

  • --source-app APP_NAME - Specify source app by name (resolves to GUID)
  • --source-space SPACE_NAME - Specify space context for app lookup or create space-level policy
  • --source-org ORG_NAME - Specify org context for space/app lookup or create org-level policy
  • --source-any - Allow any authenticated app
  • --source SOURCE - Raw GUID-based source for advanced users

remove-route-policy:

  • --source SOURCE - Required. Specify the source to remove

create-shared-domain / create-private-domain:

  • --enforce-route-policies - Require route policies for all routes on domain
  • --route-policies-scope [app|space|org] - Minimum granularity for policies

4. RFC Alignment: No User-Provided Names

Per RFC commits 882b69a and 11752f2, route policies no longer have user-provided names. They are identified by their source only, with labels/annotations available for metadata.

Key Changes:

  • Removed RULE_NAME positional argument from add-route-policy command
  • Removed Name field from RoutePolicy API resource
  • Updated route-policies list command to show 4 columns: route, source, scope, source/name
    • The source/name column shows the resolved name of the app/space/org from the source
  • Updated remove-route-policy to use --source flag instead of name
  • Renamed DeleteAccessRule()DeleteRoutePolicyBySource()

5. Enhanced Output

add-route-policy:

Adding route policy for route backend.apps.identity as admin...
  scope: app, source name: frontend-app
  source: cf:app:d76446a1-f429-4444-8797-be2f78b75b08
OK

route-policies:

route                            source                                         scope   source/name
backend.apps.identity            cf:app:d76446a1-f429-4444-8797-be2f78b75b08    app     frontend-app
api.apps.identity/metrics        cf:space:2b26e210-1b48-4e60-8432-f24bc5927789  space   monitoring
public-api.apps.identity         cf:any                                         any     

6. Validation & Error Handling

  • Validates exactly one primary source is specified
  • Provides helpful error messages when app not found in current space
  • Suggests using --source-space and --source-org flags for cross-space/org access
  • Follows CF CLI patterns from add-network-policy command

Testing

  • ✅ Comprehensive test coverage for all commands
  • ✅ Updated actor tests for new terminology
  • ✅ All tests passing
  • ✅ Covers validation, resolution, error handling, and cross-space/org scenarios
  • ✅ CLI binary builds successfully (./out/cf)
  • ✅ Help text verified for all commands

Breaking Changes

This is a complete rebrand with no backward compatibility:

  • All command names changed
  • All API paths changed
  • All resource field names changed
  • All flags renamed

This is acceptable since:

  1. The RFC has not reached GA
  2. Only POC/lab implementations exist
  3. The RFC itself was updated with these breaking changes
  4. Clean cut-over is better than long deprecation for pre-GA features

Files Changed

  • 95 total files modified (including generated fakes)
  • 20 core source files renamed/updated
  • Key areas:
    • Resources: route_policy_resource.go
    • API client: route_policy.go, api_routes.go, query.go
    • Actor: route_policy.go, error types, interfaces
    • Commands: route_policies_command.go, add_route_policy_command.go, remove_route_policy_command.go
    • Domain commands: Updated flags in create_shared_domain and create_private_domain
    • Generated fakes: Regenerated with counterfeiter

Checklist

  • Tests added/updated and passing
  • Documentation (help text) updated
  • Breaking changes documented
  • Follows CF CLI conventions
  • Aligned with RFC terminology rebrand
  • Code formatted with gofmt
  • Mocks regenerated with counterfeiter
  • CLI binary builds successfully
  • Manual testing against live CF deployment (requires CAPI backend support)

Next Steps

This PR is marked as draft pending:

  1. Coordination with CAPI team to ensure API implementation uses new terminology
  2. Manual testing against a CF deployment with route policies API support
  3. Integration testing with full CF ecosystem
  4. Review from CF CLI maintainers

Related

Co-authored-by: Ruben Koster rkoster@starkandwayne.com

@rkoster
Copy link
Copy Markdown
Author

rkoster commented Apr 10, 2026

Don't worry about this PR just yet, just doing some more POC work on the RFC: cloudfoundry/community#1438

@rkoster rkoster changed the title Enhance add-access-rule command UX with intuitive name-based flags Implement identity-aware routing RFC with route policies terminology Apr 21, 2026
rkoster added 4 commits April 21, 2026 13:01
This commit improves the user experience for the add-access-rule command
by replacing the positional GUID-based SELECTOR argument with intuitive
flags that accept human-readable names and support cross-space/org resolution.

Changes:

**Command Interface:**
- Remove positional SELECTOR argument (breaking change, acceptable for unreleased feature)
- Add new flags: --source-app, --source-space, --source-org, --source-any, --selector
- Support hierarchical name resolution:
  - --source-app APP_NAME (looks in current space)
  - --source-app APP_NAME --source-space SPACE (cross-space in current org)
  - --source-app APP_NAME --source-space SPACE --source-org ORG (cross-org)
  - --source-space SPACE (space-level rule)
  - --source-org ORG (org-level rule)
  - --source-any (allow any authenticated app)
  - --selector SELECTOR (raw GUID-based selector for advanced users)
- Validate exactly one primary source is specified
- Display verbose output showing resolved selector for transparency

**Terminology Update:**
- Rename all "target" terminology to "source" throughout codebase
- Access rules specify the source (who can access), not the target
- Update AccessRuleWithRoute.TargetName → SourceName
- Update resolveAccessRuleTarget() → resolveAccessRuleSource()
- Update access-rules list command table header: "target" → "source"

**Error Handling:**
- Provide helpful error messages when app not found in current space
- Suggest using --source-space and --source-org flags for cross-space/org access
- Follow CF CLI patterns from add-network-policy command

**Testing:**
- Add 17 comprehensive test cases for add-access-rule command
- Update 19 actor tests to use new SourceName field
- All tests passing (36/36)

**Domain Integration:**
- Add enforce_access_rules support to create-shared-domain and create-private-domain
- Add --enforce-access-rules and --access-rules-scope flags
- Update domain resource with new fields

Examples:

  # Simple case - app in current space
  cf add-access-rule allow-frontend apps.identity --source-app frontend-app --hostname backend

  # Cross-space access
  cf add-access-rule allow-other apps.identity --source-app api-client --source-space other-space --hostname backend

  # Cross-org access
  cf add-access-rule allow-prod apps.identity --source-app client --source-space prod-space --source-org prod-org --hostname api

  # Space-level rule
  cf add-access-rule allow-monitoring apps.identity --source-space monitoring --hostname api

  # Org-level rule
  cf add-access-rule allow-platform apps.identity --source-org platform --hostname shared-api

  # Any authenticated app
  cf add-access-rule allow-all apps.identity --source-any --hostname public-api

Related to: cloudfoundry/community#1438
Per RFC commits 882b69a and 11752f2, access rules no longer have
user-provided names. They are identified by their selector only,
with labels/annotations used for metadata instead.

Changes:
- Removed RULE_NAME argument from add-access-rule command
- Removed Name field from AccessRule API resource
- Updated access-rules list to show 4 columns (route, selector, scope, source)
  - SourceName now represents resolved app/space/org name from selector
- Updated remove-access-rule to use --selector flag instead of rule name
- Renamed DeleteAccessRule() to DeleteAccessRuleBySelector()
- Updated all tests to remove Name field references

All tests passing.
…lumns

Changed table format from:
  route                    selector  scope  source
  backend.apps.identity    ...       app    frontend-app

To:
  host     domain          path     selector  scope  source
  backend  apps.identity            ...       app    frontend-app
  api      apps.identity   /metrics ...       space  monitoring

This provides better clarity by separating the route components into
individual columns, making it easier to scan and filter visually.
…urce

Complete terminology shift for identity-aware routing RFC implementation:

**Access Rules → Route Policies**
- API: /v3/access_rules → /v3/route_policies
- CLI commands:
  - cf access-rules → cf route-policies
  - cf add-access-rule → cf add-route-policy
  - cf remove-access-rule → cf remove-route-policy
- Domain flags: --enforce-access-rules → --enforce-route-policies
- Domain fields: enforce_access_rules → enforce_route_policies,
  access_rules_scope → route_policies_scope

**Selector → Source**
- API field: "selector" → "source"
- CLI flag: --selector → --source
- Query params: selectors → sources, selector_resource_guids → source_guids
- Table column headers: "selector/source" → "source/name"
- Internal types: AccessRule → RoutePolicy, AccessRuleWithRoute → RoutePolicyWithRoute
- Error types: AccessRuleNotFoundError → RoutePolicyNotFoundError

**Rationale (per RFC)**
- "Route policies" aligns with existing CF "network policies" terminology
- "Source" matches C2C network policy convention (source → destination)
- Improves clarity: policies define allowed sources that can reach routes
- Better mental model for users familiar with CF networking concepts

This is a breaking change but acceptable since RFC is pre-GA with only
POC/lab implementations. Clean terminology is preferred over backward
compatibility at this stage.

Co-authored-by: RFC Community <cloudfoundry/community#1438>
Aligns-with: cloudfoundry/community@be8d74c1
@rkoster rkoster force-pushed the enhance-add-access-rule-ux branch from a0ffff8 to 9409dbb Compare April 21, 2026 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant